package com.yunda.AJDeviceService.service.impl;

import com.dahuatech.hutool.crypto.digest.DigestUtil;
import com.yunda.AJDeviceService.common.service.RedisService;
import com.yunda.AJDeviceService.common.web.domain.ErlangsAjaxResult;
import com.yunda.AJDeviceService.data.DeviceRunStatusData;
import com.yunda.AJDeviceService.data.IntelligentCheckDetailData;
import com.yunda.AJDeviceService.data.dto.*;
import com.yunda.AJDeviceService.service.DeviceRunStatusService;
import com.yunda.AJDeviceService.service.LDPSService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import java.util.HashMap;
import java.util.Map;

/**
 * @author lq
 * @className LDPSServiceImpl
 * @description TODO
 * @date 2023/2/10 11:26
 */
@Slf4j
@Service
public class LDPSServiceImpl implements LDPSService {

    @Value("${ldps.heartbeattime}")
    private Integer heartbeattime;

    @Value("${ldps.heartbeats}")
    private Integer heartbeats;

    @Value("${siteServer.ip}")
    private String pictureHostIp;

    @Value("${siteServer.picturePort}")
    private String pictureHostPort;

    @Value("${dbctCode}")
    private String fbCode;

    @Autowired
    private RedisService redisService;

    @Autowired
    private DeviceRunStatusService deviceRunStatusService;


    /**
     * 终端向LDPS注册
     * @param zdRegisterTOLdpsDto
     * @return
     */
    @Override
    public Map<String,Object> zdRegisterTOLdps(ZdRegisterTOLdpsDto zdRegisterTOLdpsDto){
        String sessionid = DigestUtil.md5Hex(zdRegisterTOLdpsDto.getId());
        Map<String,Object> map = new HashMap<String,Object>();
        map.put("sessionid",sessionid);
        map.put("heartbeattime",heartbeattime);

        String ajId = zdRegisterTOLdpsDto.getId();
        StringBuilder sessionKey = new StringBuilder();
        sessionKey.append(zdRegisterTOLdpsDto.getMethod()).append(":").append(sessionid);
        //终端和LDPS保持心跳 30 * 3 90秒后失效 即离线   可以作为是否在线标志
        redisService.set(ajId,sessionid,3600*24*30);//设备 记录 sessionid
        redisService.set(sessionKey.toString(),ajId,3600*24*30);//sessionkey 记录 设备   sessionkey=register+设备ID

        redisService.set(sessionid,ajId,heartbeattime*heartbeats);//心跳标志位

        log.info("终端向LDPS注册="+zdRegisterTOLdpsDto+" 返回注册信息="+map);
        return map;
    }

    /**
     * 心跳
     * 终端 到 ldps
     * @param zbBeatsTOLdpsDto
     * @return
     */
    @Override
    public Boolean zdBeatsTOLdps(ZbBeatsTOLdpsDto zbBeatsTOLdpsDto){

        log.info("终端向LDPS 心跳="+zbBeatsTOLdpsDto);
        //存活
        Boolean isSurvival = false;
        isSurvival = !ObjectUtils.isEmpty(redisService.get(zbBeatsTOLdpsDto.getSessionid()));

        //安检机编号
        StringBuilder sessionKey = new StringBuilder();
        sessionKey.append("register").append(":").append(zbBeatsTOLdpsDto.getSessionid());
        String ajId = redisService.get(sessionKey.toString());

        //是
        if(isSurvival)
        {
            //心跳 保活 设备开机
            log.info("终端="+ajId+" 向LDPS发送 心跳成功="+zbBeatsTOLdpsDto);
            redisService.set(zbBeatsTOLdpsDto.getSessionid(),ajId,heartbeattime*heartbeats);

            DeviceRunStatusData deviceRunStatusData = new DeviceRunStatusData();
            deviceRunStatusData.setFbCode(Integer.parseInt(fbCode));
            deviceRunStatusData.setDeviceCode(ajId);
            deviceRunStatusData.setDeviceSupplier("els");//设备供应商 二郎神
            deviceRunStatusService.uploadDeviceStatus(deviceRunStatusData);
            return true;
        }
        //否
        else
        {
            log.error("终端="+ajId+" 向LDPS发送 心跳失败="+zbBeatsTOLdpsDto+" 二郎神终端未存活");
            return false;
        }
    }

    /**
     * 注销注册
     * @param zdUnRegisterTOLdpsDto
     * @return
     */
    @Override
    public Boolean zdUnRegisterTOLdps(ZdUnRegisterTOLdpsDto zdUnRegisterTOLdpsDto){

        log.info("终端向LDPS 注销注册="+zdUnRegisterTOLdpsDto);
        //存活
        Boolean isSurvival = false;
        isSurvival = !ObjectUtils.isEmpty(redisService.get(zdUnRegisterTOLdpsDto.getSessionid()));

        //安检机编号
        StringBuilder sessionKey = new StringBuilder();
        sessionKey.append("register").append(":").append(zdUnRegisterTOLdpsDto.getSessionid());
        String ajId = redisService.get(sessionKey.toString());

        //是
        if(isSurvival)
        {
            log.info("终端向LDPS="+ajId+"  注销注册="+zdUnRegisterTOLdpsDto);
            redisService.delete(zdUnRegisterTOLdpsDto.getSessionid());
            return true;
        }
        //否
        else
        {
            log.error("终端向LDPS="+ajId+" 注销注册失败="+zdUnRegisterTOLdpsDto+" 二郎神终端安检机已下线");
            return false;
        }
    }

    /**
     * 获取KMS服务器信息
     * @param zdGetKmsInfoDto
     * @return
     */
    @Override
    public String zdGetKmsInfoTOLdps(ZdGetKmsInfoDto zdGetKmsInfoDto){

        log.info("终端向LDPS 获取KMS服务器信息="+zdGetKmsInfoDto);

        //存活
        Boolean isSurvival = false;
        isSurvival = !ObjectUtils.isEmpty(redisService.get(zdGetKmsInfoDto.getSessionid()));

        //是
        if(isSurvival)
        {
            log.info("终端向LDPS 获取KMS服务器信息 成功"+zdGetKmsInfoDto);
            return pictureHostIp+":"+pictureHostPort;
        }
        //否
        else
        {
            log.error("终端向LDPS 获取KMS服务器信息 失败  二郎神终端未存活"+zdGetKmsInfoDto);
            return null;
        }
    }

    /**
     * 上传安检员信息
     * @param zduploadinspectorToLdpsDto
     * @return
     */
    @Override
    public Boolean zduploadinspectorTOLdps(ZduploadinspectorToLdpsDto zduploadinspectorToLdpsDto){

        log.info("终端向LDPS 上传安检员信息="+zduploadinspectorToLdpsDto);
        //存活
        Boolean isSurvival = false;
        isSurvival = !ObjectUtils.isEmpty(redisService.get(zduploadinspectorToLdpsDto.getSessionid()));

        //是
        if(isSurvival)
        {
            log.info("终端向LDPS 上传安检员信息 成功"+zduploadinspectorToLdpsDto);
            return true;
        }
        //否
        else
        {
            log.error("终端向LDPS 上传安检员信息 失败  二郎神终端未存活"+zduploadinspectorToLdpsDto);
            return false;
        }
    }

    /**
     * 上传安检机运行状态数据
     * @param zbuploadsmstatusToLdpsDto
     * @return
     */
    @Override
    public Boolean zduploadsmstatusTOLdps(ZbuploadsmstatusToLdpsDto zbuploadsmstatusToLdpsDto){

        log.info("终端向LDPS 上传安检机运行状态数据="+zbuploadsmstatusToLdpsDto);
        //存活
        Boolean isSurvival = false;
        isSurvival = !ObjectUtils.isEmpty(redisService.get(zbuploadsmstatusToLdpsDto.getSessionid()));

        //是
        if(isSurvival)
        {
            log.info("终端向LDPS 上传安检机运行状态数据="+zbuploadsmstatusToLdpsDto);
            return true;
        }
        //否
        else
        {
            log.error("终端向LDPS 上传安检机运行状态数据 失败  二郎神终端未存活"+zbuploadsmstatusToLdpsDto);
            return false;
        }
    }

    /**
     * 上传安检机采集的图片
     * 目前 不处理 数据 只对接 违禁图片数据
     * @param zduploadsmimageToLdpsDto
     * @return
     */
    @Override
    public Boolean zduploadsmimageTOLdps(ZduploadsmimageToLdpsDto zduploadsmimageToLdpsDto){

        log.info("终端向LDPS 上传安检机采集的图片="+zduploadsmimageToLdpsDto);
        //存活
        Boolean isSurvival = false;
        isSurvival = !ObjectUtils.isEmpty(redisService.get(zduploadsmimageToLdpsDto.getSessionid()));

        //是
        if(isSurvival)
        {
            log.info("终端向LDPS 上传安检机采集的图片="+zduploadsmimageToLdpsDto);
            return true;
        }
        //否
        else
        {
            log.error("终端向LDPS 上传安检机采集的图片 失败 二郎神终端未存活="+zduploadsmimageToLdpsDto);
            return false;
        }
    }

    /**
     * 上传安检机采集的违禁图片
     * @param zduploadsmcontrabandToLdpsDto
     * @return
     */
    @Override
    public ErlangsAjaxResult zduploadsmcontrabandTOLdps(ZduploadsmcontrabandToLdpsDto zduploadsmcontrabandToLdpsDto){

        log.info("终端向LDPS 上传安检机采集的违禁图片="+zduploadsmcontrabandToLdpsDto);
        ErlangsAjaxResult erlangsAjaxResult = new ErlangsAjaxResult();
        //存活
        Boolean isSurvival = false;
        isSurvival = !ObjectUtils.isEmpty(redisService.get(zduploadsmcontrabandToLdpsDto.getSessionid()));
        //是
        if(isSurvival)
        {
            IntelligentCheckDetailData intelligentCheckDetailData = new IntelligentCheckDetailData();


            erlangsAjaxResult = ErlangsAjaxResult.success();
            log.info("终端向LDPS 上传安检机采集的图片 成功="+erlangsAjaxResult);
            return erlangsAjaxResult;
        }
        //否
        else
        {
            erlangsAjaxResult = ErlangsAjaxResult.error(500,"终端未存活，不能上传安检机采集的违禁图片");
            log.error("终端向LDPS 上传安检机采集的图片 失败 二郎神终端未存活="+erlangsAjaxResult);
            return erlangsAjaxResult;
        }
    }

}
